package com.wowangz.cms.component.datagrid.utils;


import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.wowangz.cms.common.utils.DataCacheMapManage;
import com.wowangz.cms.common.utils.DataDictionaryManage;
import com.wowangz.cms.common.utils.DataFormat;
import com.wowangz.cms.common.utils.MathUtils;
import com.wowangz.cms.component.datagrid.pojo.DataDepict;
import com.wowangz.cms.component.datagrid.pojo.DataDepictCacheMap;
import com.wowangz.cms.component.datagrid.pojo.DataDepictDataDictionary;
import com.wowangz.cms.component.datagrid.pojo.DataDepictFunction;
import com.wowangz.cms.component.datagrid.pojo.DataResult;
import com.wowangz.cms.component.datagrid.pojo.DataStyle;
import com.wowangz.cms.syscore.exception.ServiceException;
import com.wowangz.cms.syscore.utils.SpringUtil;


/**
 * 
 * @author leiyang3
 *
 */
public class PangingTools
{
	
	/**
	 * 根据配置信息将ResultInfo数据库结果集转换到JSONList结果集
	 * @param pagerInfo
	 * @return
	 * @throws BusinessException
	 */
	public static DataResult buildResultPagerInfo(DataStyle dataStyle) throws ServiceException
	{
		List sourceList = dataStyle.getDataList();
		Iterator sourceIter = null;
		Object sourceObj = null;
		Field[] sourceFields = null;
		Field currField = null;
		Object currFieldValue = null;
		Map sourceMap = null;
		
		DataResult dataResult = new DataResult();
		ArrayList rowList = new ArrayList(); 
		ArrayList footerList = new ArrayList(); 
		HashMap colMap = null;
		long rownum = 1;
		
		Iterator pagerIter = null;
		DataDepict dataDepict = null;
		String displayName = null;
		long displayType = -1;
		String cellString = "";
		
		Date rsDate = null;
		Timestamp rsTimestamp = null;
		double rsDouble = 0.0;
		long rsLong = 0;
		Long rsLongObj = null;
		
		Class[] argClass = null;
		Method operateMethod = null;
		Object methodObj = null;
		
		try
		{
			if(sourceList != null && sourceList.size() > 0 && dataStyle.getDataStyleList() != null)
			{
				sourceIter = sourceList.iterator();
				
				while(sourceIter.hasNext())
				{
					sourceObj = sourceIter.next();
					
					sourceMap = new HashMap();
					
					if(sourceObj instanceof HashMap){
						
						sourceMap.putAll((HashMap)sourceObj);
						
					}
					else{
						
						sourceFields = sourceObj.getClass().getDeclaredFields();
						final Class<?> supClazz = sourceObj.getClass().getSuperclass();
				        final Field[] supFields = supClazz.getDeclaredFields();
				        final Field[] tmp = new Field[sourceFields.length + supFields.length];
				        int j = 0;
				        for (Field field : supFields) {
							tmp[j]=field;
							j++;
						}
				        for (Field field : sourceFields) {
				        	tmp[j]=field;
							j++;
						}
				        sourceFields = tmp;
						for(int i=0; i<sourceFields.length; i++)
						{
							currField = sourceFields[i];
			            	currField.setAccessible(true);
			            	currFieldValue = currField.get(sourceObj);
			            	
			            	sourceMap.put(currField.getName().toUpperCase(), currFieldValue);
						}
					}


					pagerIter = dataStyle.getDataStyleList().iterator();
					colMap = new HashMap();
					
					while(pagerIter.hasNext())
					{
						dataDepict =  (DataDepict)pagerIter.next();
						
						displayName = dataDepict.getDisplayName().toUpperCase();
						int _i = 0;
								
						_i = displayName.lastIndexOf("@");
						if(_i > 0){
							displayName = displayName.substring(0, _i);
						}
						
						_i = displayName.lastIndexOf("--");
						if(_i > 0){
							displayName = displayName.substring(0, _i);
						}
						
						displayType = dataDepict.getDisplayType();
						currFieldValue = sourceMap.get(displayName);
						
						if(displayType == DataTypeConstant.STRING)
						{
							if(currFieldValue != null){
								cellString = currFieldValue.toString();
							}
							else{
								cellString = "";
							}
							
						}
						else if(displayType == DataTypeConstant.DATE)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof java.sql.Timestamp){
									rsTimestamp = (Timestamp)currFieldValue;
									cellString = DataFormat.formatDate(rsTimestamp, DataFormat.DT_YYYY_MM_DD);
								}
								else{
									rsDate = (Date)currFieldValue;
									cellString = DataFormat.formatDate(rsDate, DataFormat.DT_YYYY_MM_DD);
								}
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.DATETIME)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof java.sql.Timestamp){
									rsTimestamp = (Timestamp)currFieldValue;
									cellString = DataFormat.formatDate(rsTimestamp, DataFormat.DT_YYYYMMDD_HHMMSS);
								}
								else{
									rsDate = (Date)currFieldValue;
									cellString = DataFormat.formatDate(rsDate, DataFormat.DT_YYYYMMDD_HHMMSS);
								}
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.AMOUNT_2)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof BigDecimal){
									rsDouble = ((BigDecimal)currFieldValue).doubleValue();
								}
								else if(currFieldValue instanceof Double){
									rsDouble = ((Double)currFieldValue).doubleValue();
								}
								else{
									rsDouble = Double.valueOf(currFieldValue.toString()).doubleValue();
								}
								cellString = DataFormat.formatAmount(rsDouble, 2);
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.AMOUNT_6)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof BigDecimal){
									rsDouble = ((BigDecimal)currFieldValue).doubleValue();
								}
								else if(currFieldValue instanceof Double){
									rsDouble = ((Double)currFieldValue).doubleValue();
								}
								else{
									rsDouble = Double.valueOf(currFieldValue.toString()).doubleValue();
								}
									cellString = DataFormat.formatAmount(rsDouble, 6);
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.LONG)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof BigDecimal){
									rsLong = ((BigDecimal)currFieldValue).longValue();
								}
								else if(currFieldValue instanceof Long){
									rsLong = ((Long)currFieldValue).longValue();
								}
								else{
									rsLong = Long.valueOf(currFieldValue.toString()).longValue();
								}
								cellString = String.valueOf(rsLong);
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.DOUBLE)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof BigDecimal){
									rsDouble = ((BigDecimal)currFieldValue).doubleValue();
								}
								else if(currFieldValue instanceof Double){
									rsDouble = ((Double)currFieldValue).doubleValue();
								}
								else{
									rsDouble = Double.valueOf(currFieldValue.toString()).doubleValue();
								}
								cellString = String.valueOf(rsDouble);
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.ARRAY)
						{
							if(currFieldValue != null){
								cellString = convertArrayToString(currFieldValue, ",");
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.FUNCTION)
						{
							DataDepictFunction ddFunction = (DataDepictFunction)dataDepict;
							argClass = ddFunction.getFnArgClass();
							
							if(currFieldValue != null)
							{
								if(argClass[0].getName().equals(long.class.getName()))
								{
									if(currFieldValue instanceof BigDecimal){
										rsLong = ((BigDecimal)currFieldValue).longValue();
									}
									else if(currFieldValue instanceof Long){
										rsLong = ((Long)currFieldValue).longValue();
									}
									else{
										rsLong = Long.valueOf(currFieldValue.toString()).longValue();
									}
									
									operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);
									if(Modifier.isStatic(operateMethod.getModifiers())){
										methodObj = operateMethod.invoke(null, new Object[]{new Long(rsLong)});
									}
									else{
										// modified by fxzhang 2011-9-4 newInstance()会引起session空指针
//										methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{new Long(rsLong)});
										methodObj = operateMethod.invoke(SpringUtil.getBean(ddFunction.getFnClazz()), new Object[]{new Long(rsLong)});
									}
									cellString = String.valueOf(methodObj);
								}
								if(argClass[0].getName().equals(double.class.getName()))
								{
									if(currFieldValue instanceof BigDecimal){
										rsDouble = ((BigDecimal)currFieldValue).doubleValue();
									}
									else if(currFieldValue instanceof Long){
										rsDouble = ((Double)currFieldValue).doubleValue();
									}
									else{
										rsDouble = Double.valueOf(currFieldValue.toString()).doubleValue();
									}
									
									operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);
									if(Modifier.isStatic(operateMethod.getModifiers())){
										methodObj = operateMethod.invoke(null, new Object[]{new Double(rsDouble)});
									}
									else{
										// modified by fxzhang 2011-9-4 newInstance()会引起session空指针
//										methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{new Long(rsLong)});
										methodObj = operateMethod.invoke(SpringUtil.getBean(ddFunction.getFnClazz()), new Object[]{new Double(rsDouble)});
									}
									cellString = String.valueOf(methodObj);
								}								
								else if(argClass[0].getName().equals(Long.class.getName()))
								{
									if(currFieldValue instanceof BigDecimal){
										rsLongObj = new Long(((BigDecimal)currFieldValue).longValue());
									}
									else if(currFieldValue instanceof Long){
										rsLongObj = (Long)currFieldValue;
									}
									else{
										rsLongObj = Long.valueOf(currFieldValue.toString());
									}
									
									operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);
									if(Modifier.isStatic(operateMethod.getModifiers())){
										methodObj = operateMethod.invoke(null, new Object[]{rsLongObj});
									}
									else{
//										methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{rsLongObj});
										methodObj = operateMethod.invoke(SpringUtil.getBean(ddFunction.getFnClazz()), new Object[]{rsLongObj});
									}
									cellString = String.valueOf(methodObj);
								}
								else if(argClass[0].getName().equals(String.class.getName()))
								{
									cellString = currFieldValue.toString();
									
									operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);

									argClass = ddFunction.getFnArgClass();
									
									//if(currFieldValue != null)
									//{
										if(argClass[0].getName().equals(long.class.getName()))
										{
											if(currFieldValue instanceof BigDecimal){
												rsLong = ((BigDecimal)currFieldValue).longValue();
											}
											else if(currFieldValue instanceof Long){
												rsLong = ((Long)currFieldValue).longValue();
											}
											else{
												rsLong = Long.valueOf(currFieldValue.toString()).longValue();
											}
											
											operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);
											if(Modifier.isStatic(operateMethod.getModifiers())){
												methodObj = operateMethod.invoke(null, new Object[]{new Long(rsLong)});
											}
											else{
//												methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{new Long(rsLong)});
												methodObj = operateMethod.invoke(SpringUtil.getBean(ddFunction.getFnClazz()), new Object[]{new Long(rsLong)});
											}
											cellString = String.valueOf(methodObj);
										}
										else if(argClass[0].getName().equals(String.class.getName()))
										{
											cellString = currFieldValue.toString();
											
											operateMethod =  ddFunction.getFnClazz().getMethod(ddFunction.getFnMethodName(), argClass);
											if(Modifier.isStatic(operateMethod.getModifiers())){
												methodObj = operateMethod.invoke(null, new Object[]{new String(cellString)});
											}
											else{
//												methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{new String(cellString)});
												methodObj = operateMethod.invoke(SpringUtil.getBean(ddFunction.getFnClazz()), new Object[]{new String(cellString)});
											}
											cellString = String.valueOf(methodObj);
										}
									//}
									/*
									else{
										cellString = "";
									}
									if(Modifier.isStatic(operateMethod.getModifiers())){
										methodObj = operateMethod.invoke(null, new Object[]{new String(cellString)});
									}
									else{
//										methodObj = operateMethod.invoke(baseInfo.getFnClazz().newInstance(), new Object[]{new String(cellString)});
										methodObj = operateMethod.invoke(SpringContextHolder.getBean(ddFunction.getFnClazz()), new Object[]{new String(cellString)});
										
									}
									cellString = String.valueOf(methodObj);*/
								}
							}
							else{
								cellString = "";
							}
						}
						else if(displayType == DataTypeConstant.DATADICTIONARY)
						{
							DataDepictDataDictionary ddDataDictionary = (DataDepictDataDictionary)dataDepict;
							
							if(currFieldValue != null){
								cellString = currFieldValue.toString();
								//TODO 数据字典待实现
								cellString =DataDictionaryManage.getDataDictionaryName(ddDataDictionary.getDictCode(), cellString);
							}
							else{
								cellString = "";
							}
							
						}
						else if(displayType == DataTypeConstant.CACHEMAP)
						{
							DataDepictCacheMap cacheMap = (DataDepictCacheMap)dataDepict;
							
							if(currFieldValue != null){
								cellString = currFieldValue.toString();
								//TODO 数据字典待实现
								cellString =DataCacheMapManage.getDataCacheMapObjectName(cacheMap.getMapkey(), cellString,cacheMap.getFnClazz(),cacheMap.getFnMethodName());
							}
							else{
								cellString = "";
							}
							
						}		
						else if(displayType == DataTypeConstant.RATE_6)
						{
							if(currFieldValue != null){
								if(currFieldValue instanceof BigDecimal){
									rsDouble = ((BigDecimal)currFieldValue).doubleValue();
								}
								else if(currFieldValue instanceof Double){
									rsDouble = ((Double)currFieldValue).doubleValue();
								}
								else{
									rsDouble = Double.valueOf(currFieldValue.toString()).doubleValue();
								}
								cellString = DataFormat.formatAmount(MathUtils.mul(rsDouble, 100), 6) + "%";
							}
							else{
								cellString = "";
							}
						}
						
						//cellList.add(cellString);
						colMap.put(dataDepict.getDisplayName().toLowerCase(), cellString);
						
						cellString = "";
					}

					rowList.add(colMap);
					rownum++;
				}

				dataResult.setRows(rowList);
				dataResult.setTotal(dataStyle.getDataCount());

				if(dataStyle.getSumMap() != null && dataStyle.getSumMap().size() > 0){
					footerList.add(dataStyle.getSumMap());
					dataResult.setFooter(footerList);
				}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			throw new ServiceException("转换结果集到JSON集合时异常", e);
		}
		
		return dataResult;
	}
	
	public static String convertArrayToString(Object arrayObj, String split)
	{
		StringBuffer bufferString = new StringBuffer();
		
		if(arrayObj != null)
		{
			if(long[].class.equals(arrayObj.getClass()))
			{
				long[] arrayLong = (long[])arrayObj;
				
				for(int i=0; i<arrayLong.length; i++)
				{
					bufferString.append(arrayLong[i] + split);
				}
			}
			else if(double[].class.equals(arrayObj.getClass()))
			{
				double[] arrayDouble = (double[])arrayObj;
				
				for(int i=0; i<arrayDouble.length; i++)
				{
					bufferString.append(arrayDouble[i] + split);
				}
			}
			else if(String[].class.equals(arrayObj.getClass()))
			{
				String[] arrayString = (String[])arrayObj;
				
				for(int i=0; i<arrayString.length; i++)
				{
					bufferString.append(arrayString[i] + split);
				}
			}
		}
		
		if(!bufferString.toString().equals(""))
		{
			bufferString = new StringBuffer(bufferString.toString().substring(0, bufferString.toString().length() - split.length()));
		}
		
		return bufferString.toString();
	}
	
	public static HashMap convertFormjsonToMap(String formjson) throws ServiceException {
		
		HashMap hashMap = new HashMap();
		try {
			ObjectMapper mapper = new ObjectMapper();
			JsonNode jsonNode = mapper.readTree(formjson);
			
			Iterator<String> iter = jsonNode.getFieldNames();
			String fieldName = null;
			while(iter.hasNext()){
				fieldName = iter.next();
				hashMap.put(fieldName.toUpperCase(), jsonNode.findValue(fieldName).getTextValue());
			}
			
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			throw new ServiceException("获取查询参数异常");
		} catch (IOException e) {
			e.printStackTrace();
			throw new ServiceException("获取查询参数异常");
		}
		
		return hashMap;
	}
}
